﻿using System.Windows.Forms;
using Stl.Controls;
using Psl.Controls;
using System.ComponentModel;

namespace Stl.Tme.Components.DesignOutline
{
    /// <summary>
    /// Classe qui permet d'ajouter des commandes.
    /// </summary>
    public class AddControlCommand : Command
    {
        /// <summary>
        /// Surface concernée.
        /// </summary>
        protected DesignFrame frame;

        /// <summary>
        /// Composant concerné.
        /// </summary>
        protected Control control;

        /// <summary>
        /// Constructeur.
        /// </summary>
        /// <param name="frame"></param>
        /// <param name="control"></param>
        public AddControlCommand(DesignFrame frame, Control control)
        {
            this.frame = frame;
            this.control = control;
        }

        /// <summary>
        /// Annuler une action d'ajout.
        /// </summary>
        public override void Undo()
        {
            frame.Controls.RemoveByKey(control.Name);
        }

        /// <summary>
        /// Rétablir une action d'ajout.
        /// </summary>
        public override void Redo()
        {
            frame.Controls.Add(control);
            frame.SelectedControl = control;
        }

        /// <summary>
        /// Retourne le nom du contrôle ajouté.
        /// </summary>
        /// <returns></returns>
        public override string GetCommand()
        {
            return "Add " + control.Name;
        }
    }

    /// <summary>
    /// Classe qui permet de supprimer des commandes.
    /// </summary>
    public class RemoveControlCommand : Command
    {
        /// <summary>
        /// Surface concernée.
        /// </summary>
        protected DesignFrame frame;

        /// <summary>
        /// Composant concerné.
        /// </summary>
        protected Control control;

        /// <summary>
        /// Constructeur.
        /// </summary>
        /// <param name="frame"></param>
        /// <param name="control"></param>
        public RemoveControlCommand(DesignFrame frame, Control control)
        {
            this.frame = frame;
            this.control = control;
        }

        /// <summary>
        /// Annuler une action de suppression.
        /// </summary>
        public override void Undo()
        {
            frame.Controls.Add(control);
            frame.SelectedControl = control;
        }

        /// <summary>
        /// Rétablir une action de suppression.
        /// </summary>
        public override void Redo()
        {
            frame.Controls.Remove(control);
        }

        /// <summary>
        /// Retourne le nom du contrôle supprimé.
        /// </summary>
        /// <returns></returns>
        public override string GetCommand()
        {
            return "Remove " + control.Name;
        }
    }

    /// <summary>
    /// Classe qui permet de supprimer tous les composants.
    /// </summary>
    class ClearCommand : Command
    {
        /// <summary>
        /// Surface concernée.
        /// </summary>
        protected DesignFrame frame;

        /// <summary>
        /// Composant concerné.
        /// </summary>
        protected Control[] controls;

        /// <summary>
        /// Constructeur.
        /// </summary>
        /// <param name="frame"></param>
        /// <param name="controls"></param>
        public ClearCommand(DesignFrame frame, Control[] controls)
        {
            this.frame = frame;
            this.controls = controls;
        }

        /// <summary>
        /// Annuler l'action de suppression globale.
        /// </summary>
        public override void Undo()
        {
            frame.Controls.AddRange(controls);
        }

        /// <summary>
        /// Rétablir l'action de suppression globale.
        /// </summary>
        public override void Redo()
        {
            frame.Controls.Clear();
        }

        /// <summary>
        /// Affiche une trace de la réussite de la suppression globale.
        /// </summary>
        /// <returns></returns>
        public override string GetCommand()
        {
            return "Clear";
        }
    }

    /// <summary>
    /// Classe qui permet de gérer les changements des propriètès.
    /// </summary>
    class PropertyChangeCommand : Command
    {
        /// <summary>
        /// Composant concerné.
        /// </summary>
        protected object component;

        /// <summary>
        /// Ancienne valeur.
        /// </summary>
        protected object oldValue;

        /// <summary>
        /// Nouvelle valeur.
        /// </summary>
        protected object value;

        /// <summary>
        /// Description de la propriété concernée.
        /// </summary>
        protected PropertyDescriptor propertyDescriptor;

        /// <summary>
        /// Constructeur.
        /// </summary>
        /// <param name="component"></param>
        /// <param name="oldValue"></param>
        /// <param name="propertyDescriptor"></param>
        public PropertyChangeCommand(object component, object oldValue, PropertyDescriptor propertyDescriptor)
        {
            this.component = component;
            this.oldValue = oldValue;
            this.propertyDescriptor = propertyDescriptor;
            this.value = propertyDescriptor.GetValue(component);
        }

        /// <summary>
        /// Annuler un changement de propriété.
        /// </summary>
        public override void Undo()
        {
            propertyDescriptor.SetValue(component, oldValue);
        }

        /// <summary>
        /// Rétablir un changement de propriété.
        /// </summary>
        public override void Redo()
        {
            propertyDescriptor.SetValue(component, value);
        }

        /// <summary>
        /// Afficher une trace du changement de propriété.
        /// </summary>
        /// <returns></returns>
        public override string GetCommand()
        {
            return "Property " + (component as Control).Name + "." + propertyDescriptor.Name + "=" + value
                + " (oldValue=" + oldValue + ")";
        }
    }



}
